/*
 * This file is part of gshot.
 *
 * Gshot is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * Gshot is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 *
 * Copyright (C) 2007-2011, Victor Ananjevsky <ananasik@gmail.com>
 */

#include <config.h>

#include "gshot.h"
#include "callback.h"
#include "tray.h"

#ifdef HAVE_UNIQUE
#include <unique/unique.h>

enum {
  CMD_SCREEN=1,
  CMD_WINDOW,
  CMD_REGION,
  CMD_SAVE,
  CMD_PRINT,
  CMD_COPY,
  CMD_SHOW,
  CMD_EXIT,
  CMD_UNKNOWN,
};

static UniqueApp *uapp;
static gint ucmd = CMD_UNKNOWN;

static void 
set_command (const gchar *name, const gchar *value, gpointer d, GError **err)
{
  if (g_ascii_strcasecmp (value, "screen") == 0)
    ucmd = CMD_SCREEN;
  else if (g_ascii_strcasecmp (value, "window") == 0)
    ucmd = CMD_WINDOW;
  else if (g_ascii_strcasecmp (value, "region") == 0)
    ucmd = CMD_REGION;
  else if (g_ascii_strcasecmp (value, "save") == 0)
    ucmd = CMD_SAVE;
  else if (g_ascii_strcasecmp (value, "print") == 0)
    ucmd = CMD_PRINT;
  else if (g_ascii_strcasecmp (value, "copy") == 0)
    ucmd = CMD_COPY;
  else if (g_ascii_strcasecmp (value, "show") == 0)
    ucmd = CMD_SHOW;
  else if (g_ascii_strcasecmp (value, "exit") == 0)
    ucmd = CMD_EXIT;
}

static UniqueResponse
exec_command (UniqueApp *app, UniqueCommand cmd, UniqueMessageData *msg,
	      guint time_, gpointer d)
{
  gboolean state;
  GtkWidget *win;
  UniqueResponse ret = UNIQUE_RESPONSE_OK;

  /* save window state */
  win = GTK_WIDGET (gtk_builder_get_object (data.xml, "dialog"));
  state = gtk_widget_get_visible (win);

  /* execute command */
  switch (cmd)
    {
    case CMD_SCREEN:
      capture_image (GRAB_SCREEN);
      break;
    case CMD_WINDOW:
      capture_image (GRAB_WINDOW);
      break;
    case CMD_REGION:
      capture_image (GRAB_REGION);
      break;
    case CMD_SAVE:
      save_clicked (NULL, NULL);
      break;
    case CMD_PRINT:
      print_clicked (NULL, NULL);
      break;
    case CMD_COPY:
      copy_clicked (NULL, NULL);
      break;
    case CMD_SHOW:
      {
	GtkWidget *win = GTK_WIDGET (gtk_builder_get_object (data.xml, "dialog"));

	if (!gtk_widget_get_visible (win))
	  gtk_widget_show (win);
	gtk_widget_grab_focus (win);
	break;
      }
    case CMD_EXIT:
      gtk_main_quit ();
      break;
    default:
      ret = UNIQUE_RESPONSE_CANCEL;
      break;
    }

  /* restore window state */
  if (!state)
    gtk_widget_hide (win);

  return ret; 
}
#endif /* HAVE_UNIQUE */

typedef struct {
  gchar *name;
  gchar *cmd;
} apps_t;

GtkWidget*
create_open_menu ()
{
  GList *al, *ai;
  GtkWidget *m, *i;
  GtkTreeModel *store;
  GtkTreeIter iter;

  static GList *apps = NULL;

  m = gtk_menu_new ();

  /* get default applications */
  if (!apps)
    {
      al = g_app_info_get_all_for_type ("image/png");
      for (ai = al; ai; ai = ai->next)
	{
	  apps_t *app;

	  app = g_new0 (apps_t, 1);
	  app->name = g_strdup (g_app_info_get_display_name ((GAppInfo *) ai->data));
	  app->cmd = g_strdup_printf ("%s %%F", g_app_info_get_executable ((GAppInfo *) ai->data));
	  apps = g_list_append (apps, app);
	}
      g_list_free (al);
    }

  /* add default applications */
  for (ai = apps; ai; ai = ai->next)
    {
      apps_t *app = (apps_t *) ai->data;
      i = gtk_menu_item_new_with_label (app->name);
      gtk_widget_show (i);
      g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (open_in_cb), app->cmd);
      gtk_menu_shell_append (GTK_MENU_SHELL (m), i);
    }

  /* add custom scripts */
  store = GTK_TREE_MODEL (gtk_builder_get_object (data.xml, "scripts_store"));
  if (gtk_tree_model_get_iter_first (store, &iter))
    {
      i = gtk_separator_menu_item_new ();
      gtk_widget_show (i);
      gtk_menu_shell_append (GTK_MENU_SHELL (m), i);
  
      do
	{
	  gchar *name, *cmd;
      
	  gtk_tree_model_get (store, &iter, 0, &name, 1, &cmd, -1);

	  i = gtk_menu_item_new_with_label (name);
	  gtk_widget_show (i);
	  g_signal_connect (G_OBJECT (i), "activate", G_CALLBACK (open_in_cb), cmd);
	  gtk_menu_shell_append (GTK_MENU_SHELL (m), i);
	}
      while (gtk_tree_model_iter_next (store, &iter));
    }

  return m;
}

gint
main (gint argc, gchar *argv[])
{
  GtkWidget *w;
  gchar *dname, *fname;
  GDir *dir;
#ifdef HAVE_UNIQUE
  GOptionContext *cnt;
  GOptionEntry ents[] = {
    {"command", 'c', 0, G_OPTION_ARG_CALLBACK, set_command,                                  
     N_("execute specific command. Commands are: screen, window, region, save, print, copy, show or exit"), 
     N_("CMD")},
    { NULL }
  };
#endif

#ifdef ENABLE_NLS
  bindtextdomain (GETTEXT_PACKAGE, LOCALEDIR);
  bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
  textdomain (GETTEXT_PACKAGE);
#endif

  gtk_init (&argc, &argv);

#ifdef HAVE_UNIQUE
  uapp = unique_app_new_with_commands ("org.freedesktop.Gshot", NULL,
				       "screen", CMD_SCREEN,
				       "window", CMD_WINDOW,
				       "region", CMD_REGION,
				       "save", CMD_SAVE,
				       "print", CMD_PRINT,
				       "show", CMD_SHOW,
				       "exit", CMD_EXIT,
				       "unknown", CMD_UNKNOWN,
                                      NULL);
  
  cnt = g_option_context_new ("");
  g_option_context_set_summary (cnt, _("Make a screenshot"));
  g_option_context_add_main_entries (cnt, ents, GETTEXT_PACKAGE);
  g_option_context_add_group (cnt, gtk_get_option_group (TRUE));    
  g_option_context_parse (cnt, &argc, &argv, NULL);

  if (unique_app_is_running (uapp)) 
    return unique_app_send_message (uapp, ucmd, NULL);
#endif

  data.xml = gtk_builder_new ();
  gtk_builder_add_from_file (data.xml, DATADIR "/gshot.ui", NULL);
  gtk_builder_set_translation_domain (data.xml, GETTEXT_PACKAGE);

  /* must be after initialize ui !!! */
  read_settings ();

  /* setup initial values */
  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "mode_combo"));
  gtk_combo_box_set_active (GTK_COMBO_BOX (w), data.mode);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "delay_scale"));
  gtk_range_set_value (GTK_RANGE (w), data.delay);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "frame_check"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), data.frame);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "hide_check"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), data.hide);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "folder_button"));
  gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (w), data.folder);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "tray_check"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), data.tray);

  w = GTK_WIDGET (gtk_builder_get_object (data.xml, "tray_hide_check"));
  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (w), data.tray_hide);

  g_object_set_data (gtk_builder_get_object (data.xml, "scripts_name_cel"),
                     "col", GINT_TO_POINTER (0));
  g_object_set_data (gtk_builder_get_object (data.xml, "scripts_cmd_cel"),
                     "col", GINT_TO_POINTER (1));
  
  gtk_builder_connect_signals (data.xml, NULL);

  /* setup tray */
  if (data.tray)
    {
      show_tray ();
      if (data.tray_hide)
        gtk_widget_hide (GTK_WIDGET (gtk_builder_get_object (data.xml, "dialog")));
      else
        gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (data.xml, "dialog")));
    }
  else
    {
      gtk_widget_show (GTK_WIDGET (gtk_builder_get_object (data.xml, "dialog")));
      gtk_widget_set_sensitive (w, FALSE);
    }

#ifdef HAVE_UNIQUE
  /* register unique application */
  unique_app_watch_window (uapp, GTK_WINDOW (gtk_builder_get_object (data.xml, "dialog")));
  g_signal_connect (uapp, "message-received", G_CALLBACK (exec_command), NULL);
#endif

  gtk_main ();

  save_settings ();

#ifdef HAVE_UNIQUE
  g_object_unref (uapp);
#endif

  /* cleanup temp files */
  dname = g_build_filename (g_getenv ("TMPDIR") ? g_getenv ("TMPDIR") : "/tmp", "gshot", NULL);
  dir = g_dir_open (dname, 0, NULL);
  while (fname = (gchar *) g_dir_read_name (dir))
    unlink (fname);
  g_dir_close (dir);
  g_rmdir (dname);
  g_free (dname);
  
  return 0;
}
